/*
* JSA Test Suit
*
* @package jsa-tests
* @author sheiko
* @version jsa.js, v 2.0
* @license MIT
* @copyright (c) Dmitry Sheiko http://www.dsheiko.com
* Code style: http://docs.jquery.com/JQuery_Core_Style_Guidelines
*/
var App = App || {};
(function( jsa, App, undefined ) {
    /**
     * Check the behavior derived from WidgetAbstract
     */
    App.TestWidget = function( settings ) {
         return {
             extend: jsa.WidgetAbstract,
             HTML_PARSER : {
               wrapper : 'div.wrapper',
               subject : 'p.subject'
             },
             init : function() {
                 this.node.boundingBox.addClass( 'init' );
             },
             syncUI : function() {
                 this.node.boundingBox.addClass( 'syncUI' );
             },
             renderUI : function() {
                 this.node.boundingBox.addClass( 'renderUI' );
                 if (this.node.wrapper.length) {
                     this.node.boundingBox.addClass( 'wrapperFound' );
                 }
                 if (this.node.subject.length) {
                     this.node.boundingBox.addClass( 'subjectFound' );
                 }
             }
          }
     };
     /**
      * Checks module inheritance
      */
     App.log = [];

     App.AbstractModule = function( settings ) {
         var _privateVar = "abstract-private-access";
         return {
             extend: jsa.WidgetAbstract,
             inheritedProp : "inherited-prop-access",
             inheritedPrivilegedMethod : function() {
                 return _privateVar;
             },
             init : function() {
                App.log.push( 'abstract-module-initialized' );
             },
             renderUI : function() {
                 App.log.push( 'abstract-module-rendered' );
             },
             syncUI : function() {
                 App.log.push( 'abstract-module-synchronized' );
             }
         }
     };

     App.ConcreteModule = function( settings ) {
         return {
            extend: App.AbstractModule,
            init : function() {
                App.log.push( 'concrete-module-initialized' );
            },
            renderUI : function() {
                 App.log.push( 'abstract-module-rendered' );
            },
            syncUI : function() {
                 App.log.push( 'abstract-module-synchronized' );
            }
          }
     };
     /**
      * Check interface implementation
      */
     App.ViolatingModule = function() {
         return {
             implement: App.ConcreteInterface
         };
     };

     App.InjectedDependency = function() {
         return {
         };
     };

     App.ConcreteInterface = {
         requeriedMethod : ["string", App.InjectedDependency]
     };

     App.StrictModule = function() {
         return {
             implement: App.ConcreteInterface,
             requeriedMethod : function() {
             }
         }
     };
     /*
      * Check design by contract implementation
      */
     App.ConcreteContract = {
         methodA : [ "number", App.InjectedDependency ],
         methodB : {
              onEntry: [ "number", App.InjectedDependency ],
              validators: [function(arg){
                  return arg > 10;
              }],
              onExit: "string"
          },
          methodC : {
              onExit: "string"
          }
     };
     App.EmployedModule = function() {
         return {
             contract: App.ConcreteContract,
             methodA : function() {
             },
             methodB : function() {
                 return "a string";
             },
             methodC : function() {
                 return []; // Not a string
             }
         }
     };


     App.MixinA = {
         propertyA: "propertyA"
     };
     App.MixinB = {
         propertyB: "propertyB"
     };
     App.Silo = function() {
         return {
             mixin: [ App.MixinA, App.MixinB ],
             ownPropery: "Own property"
         }
     };


 })( jsa, App );
